<template>
    <div class="page-container">
        <!-- Banner布局选择器 -->
        <div class="preview-section">
            <div class="mobile-mockup">
                <div class="iframe-container" style="position:relative;">
                    <!--                    <iframe ref="previewIframe" src="http://192.168.31.105:8081/rightType/index/index" frameborder="0" class="preview-iframe"></iframe>-->
                    <iframe ref="previewIframe"  :src="getIframeSrc()" frameborder="0" class="preview-iframe"></iframe>
                </div>
            </div>
        </div>
        <div class="editor-section">
            <el-tabs v-model="activeTab">
                <el-tab-pane label="页面设置" name="settings">
                    <div class="editor-content">
                        <el-collapse v-model="activeCollapse">
                            <template v-for="orderKey in orderListMap">
                                <el-collapse-item
                                    v-if="orderKey.startsWith('banner_index')"
                                    :ref="orderKey === 'banner_index' ? 'bannerCollapse' : null"
                                    :title="componentOrder.find(c => c.name === (orderKey === 'banner_index' ? 'banner' : orderKey.replace('banner_index', 'banner')))?.title || '轮播图'"
                                    :name="orderKey === 'banner_index' ? 'banner' : orderKey"
                                    :key="orderKey"
                                >
                                    <!-- 轮播图内容原样插入 -->
                                    <template v-if="orderKey === 'banner_index'">
                                        <!-- Banner布局选择器放在轮播图设置顶部 -->
                                        <div class="banner-type-selector">
                                            <div
                                                v-for="option in bannerTypeOptions"
                                                :key="option.type"
                                                :class="['banner-type-item', { active: banner_type === option.type }, option.icon]"
                                                @click="selectBannerType(option.type)"
                                            >
                                                <div class="banner-type-icon-v2">
                                                    <template v-if="option.type === 1">
                                                        <!-- 布局1: 左右各一个大块 -->
                                                        <div class="rect big" style="left:2px;top:2px;width:10px;height:18px;"></div>
                                                        <div class="rect big" style="left:20px;top:2px;width:10px;height:18px;"></div>
                                                    </template>
                                                    <template v-else-if="option.type === 2">
                                                        <!-- 布局2: 左二右一（左上、左下小块，右侧大块） -->
                                                        <div class="rect small" style="left:2px;top:2px;width:9px;height:7px;"></div>
                                                        <div class="rect small" style="left:2px;top:14px;width:9px;height:7px;"></div>
                                                        <div class="rect big" style="left:14px;top:2px;width:15px;height:18px;"></div>
                                                    </template>
                                                    <template v-else-if="option.type === 3">
                                                        <!-- 布局3: 左一右二（左侧大块，右上、右下小块） -->
                                                        <div class="rect big" style="left:2px;top:2px;width:16px;height:18px;"></div>
                                                        <div class="rect small" style="left:22px;top:2px;width:9px;height:7px;"></div>
                                                        <div class="rect small" style="left:22px;top:14px;width:9px;height:7px;"></div>
                                                    </template>
                                                    <template v-else>
                                                        <!-- 布局4: 横向大块 -->
                                                        <div class="rect big" style="left:2px;top:8px;width:28px;height:8px;"></div>
                                                    </template>
                                                </div>
                                                <div class="banner-type-label">{{ option.label }}</div>
                                            </div>
                                        </div>
                                    </template>
                                    <!-- 下面是轮播图图片上传等内容 -->
                                    <div v-for="banner in pageConfig.banner.items.filter(item => item.state !== -1)" :key="banner._uuid || banner.id" class="setting-block">
                                        <el-upload
                                            :action="'/admin/diy/imgUpload'"
                                            :headers="{ token: userInfo.token }"
                                            :data="{ type: 2 }"
                                            :show-file-list="false"
                                            :on-success="(res, file, fileList) => handleBannerUploadSuccess(res, file, fileList, banner.id, banner._uuid)"
                                            :before-upload="beforeExcelUpload"
                                        >
                                            <img :src="banner.imageUrl" class="editor-image" />
                                            <i v-if="!banner.imageUrl" class="el-icon-plus uploader-icon"></i>
                                        </el-upload>
                                        <p style="color: #888; font-size: 12px; margin: 4px 0 0 0;">建议尺寸 3240 × 1200</p>
                                    </div>
                                    <div v-if="!pageConfig.banner.items.filter(item => item.state !== -1).length" class="setting-block">
                                        <p>暂无轮播图</p>
                                        <el-button type="primary" size="small" @click="addFirstBanner">添加轮播图</el-button>
                                    </div>
                                </el-collapse-item>
                                <el-collapse-item
                                    v-else-if="orderKey.startsWith('clas')"
                                    :ref="orderKey === 'clas' ? 'iconNavCollapse' : null"
                                    :title="componentOrder.find(c => c.name === (orderKey === 'clas' ? 'iconNav' : orderKey.replace('clas', 'iconNav')))?.title || '图标导航'"
                                    :name="orderKey === 'clas' ? 'iconNav' : orderKey"
                                    :key="orderKey"
                                >
                                    <!-- 图标导航内容原样插入 -->
                                    <div style="margin-bottom: 8px;">
                                        <span style="font-size:12px;">背景色：</span>
                                        <el-color-picker v-model="clasBgc" size="mini" style="vertical-align: middle;" />
                                    </div>
                                    <div class="setting-block">
                                        <p>一行显示个数</p>
                                        <el-slider v-model="pageConfig.iconNav.itemsPerRow" :min="3" :max="5" show-stops></el-slider>
                                    </div>
                                    <div v-for="item in pageConfig.iconNav.items.filter(item => item.state !== -1)" :key="item._uuid || item.id" class="setting-block" :style="{ marginBottom: (item.style?.blockMargin ?? pageConfig.iconNav.style.blockMargin ?? 20) + 'px' }">
                                        <el-upload
                                            :action="'/admin/diy/imgUpload'"
                                            :headers="{ token: userInfo.token }"
                                            :data="{ type: 2 }"
                                            :show-file-list="false"
                                            :on-success="(res, file, fileList) => handleIconUploadSuccess(res, file, fileList, item.id, item._uuid)"
                                            :before-upload="beforeExcelUpload"
                                        >
                                            <img v-if="item.imageUrl" :src="item.imageUrl" class="editor-image" style="width: 50px;height: 50px"/>
                                            <i v-if="!item.imageUrl" class="el-icon-plus uploader-icon"></i>
                                        </el-upload>
                                        <p style="color: #888; font-size: 12px; margin: 4px 0 0 0;">建议尺寸 48 × 48</p>
                                        <div class="inline-settings">
                                            <el-color-picker v-model="item.style.textColor" size="mini"></el-color-picker>
                                            <el-input-number v-model="item.style.fontSize" size="mini" :min="10" :max="16"></el-input-number>
                                        </div>
                                        <div style="width: 100%;display: flex;align-items: center;margin-top: 10px;">
                                            <el-button size="small" @click="editThird(item)">设置三级分类</el-button>
                                        </div>
                                    </div>
                                    <div class="setting-block">
                                        <p>板块间间距</p>
                                        <el-input-number v-model="pageConfig.iconNav.style.itemGap" size="mini" :min="0" :max="50"></el-input-number>
                                    </div>
                                    <div class="setting-block">
                                        <p>与父板块间距</p>
                                        <el-input-number v-model="pageConfig.iconNav.style.blockMargin" size="mini" :min="0" :max="100"></el-input-number>
                                    </div>
                                    <div v-if="!pageConfig.iconNav.items.filter(item => item.state !== -1).length" class="setting-block">
                                        <p>暂无图标导航</p>
                                        <el-button type="primary" size="small" @click="addFirstIconNav">添加图标导航</el-button>
                                    </div>
                                </el-collapse-item>
                                <el-collapse-item
                                    v-else-if="orderKey.startsWith('recommend_goods')"
                                    :ref="orderKey === 'recommend_goods' ? 'productsCollapse' : null"
                                    :title="componentOrder.find(c => c.name === (orderKey === 'recommend_goods' ? 'products' : orderKey.replace('recommend_goods', 'products')))?.title || '商品推荐'"
                                    :name="orderKey === 'recommend_goods' ? 'products' : orderKey"
                                    :key="orderKey"
                                >
                                    <!-- 商品推荐内容原样插入 -->
                                    <div style="margin-bottom: 8px;">
                                        <span style="font-size:12px;">背景色：</span>
                                        <el-color-picker v-model="recommendGoodsBgc" size="mini" style="vertical-align: middle;" />
                                    </div>
                                    <div class="setting-block">
                                        <p>排版</p>
                                        <el-radio-group v-model="pageConfig.products.layout" size="small">
                                            <el-radio-button label="grid">网格</el-radio-button>
                                            <el-radio-button label="list">列表</el-radio-button>
                                        </el-radio-group>
                                    </div>
                                    <div v-for="product in pageConfig.products.items.filter(item => item.state !== -1)" :key="product._uuid || product.id" class="setting-block" :style="{ marginBottom: (product.style?.blockMargin ?? pageConfig.products.style.blockMargin ?? 24) + 'px' }">
                                        <el-upload
                                            :action="'/admin/diy/imgUpload'"
                                            :headers="{ token: userInfo.token }"
                                            :data="{ type: 2 }"
                                            :show-file-list="false"
                                            :on-success="(res, file, fileList) => handleProductUploadSuccess(res, file, fileList, product.id, product._uuid)"
                                            :before-upload="beforeExcelUpload"
                                        >
                                            <img v-if="product.imageUrl" :src="product.imageUrl" class="editor-image" />
                                            <i v-if="!product.imageUrl" class="el-icon-plus uploader-icon"></i>
                                        </el-upload>
                                        <p style="color: #888; font-size: 12px; margin: 4px 0 0 0;">建议尺寸 1440 × 1200</p>
                                        <div class="inline-settings">
                                            <el-color-picker v-model="product.style.textColor" size="mini"></el-color-picker>
                                            <el-input-number v-model="product.style.fontSize" size="mini" :min="10" :max="24"></el-input-number>
                                        </div>
                                        <div class="inline-settings">
                                            <el-button type="primary" size="small" @click="toShopDetail(product)">商品详情</el-button>
                                        </div>
                                    </div>
                                    <div class="setting-block">
                                        <p>板块间间距</p>
                                        <el-input-number v-model="pageConfig.products.style.itemGap" size="mini" :min="0" :max="50"></el-input-number>
                                    </div>
                                    <div class="setting-block">
                                        <p>与父板块间距</p>
                                        <el-input-number v-model="pageConfig.products.style.blockMargin" size="mini" :min="0" :max="100"></el-input-number>
                                    </div>
                                    <div class="setting-block">
                                        <p>排版方式</p>
                                        <el-select v-model="pageConfig.products.style.layoutType" size="small">
                                            <el-option label="网格" value="grid"/>
                                            <el-option label="列表" value="list"/>
                                            <el-option label="错落" value="staggered"/>
                                        </el-select>
                                    </div>
                                    <div v-if="!pageConfig.products.items.filter(item => item.state !== -1).length" class="setting-block">
                                        <p>暂无商品推荐</p>
                                        <el-button type="primary" size="small" @click="addFirstProduct">添加商品推荐</el-button>
                                    </div>
                                </el-collapse-item>
                            </template>
                        </el-collapse>
                    </div>
                    <div class="editor-footer">
                        <el-button @click="cancelChanges" :disabled="!isDirty" size="small">取消</el-button>
                        <el-button type="primary" @click="saveChanges" :disabled="!isDirty" size="small">保存</el-button>
                    </div>
                </el-tab-pane>
                <el-tab-pane label="拖拽排序" name="drag">
                    <div class="drag-section">
                        <h3>拖拽组件重新排序</h3>
                        <p class="drag-tip">点击前台页面中的组件进行选择，然后拖拽下方组件进行排序</p>

                        <div class="component-list">
                            <div
                                v-for="(orderKey, index) in orderListMap"
                                :key="orderKey"
                                class="component-item"
                                :class="{ 'selected': selectedComponent === (orderKey.startsWith('banner_index') ? 'banner' : orderKey.startsWith('clas') ? 'iconNav' : orderKey.startsWith('recommend_goods') ? 'products' : orderKey) }"
                                draggable="true"
                                @dragstart="handleDragStart($event, index)"
                                @dragover.prevent
                                @drop="handleDrop($event, index)"
                                @click="selectComponent(orderKey.startsWith('banner_index') ? 'banner' : orderKey.startsWith('clas') ? 'iconNav' : orderKey.startsWith('recommend_goods') ? 'products' : orderKey)"
                            >
                                <i :class="componentOrder.find(c => c.name === (orderKey.startsWith('banner_index') ? 'banner' : orderKey.startsWith('clas') ? 'iconNav' : orderKey.startsWith('recommend_goods') ? 'products' : orderKey))?.icon"></i>
                                <span>{{ componentOrder.find(c => c.name === (orderKey.startsWith('banner_index') ? 'banner' : orderKey.startsWith('clas') ? 'iconNav' : orderKey.startsWith('recommend_goods') ? 'products' : orderKey))?.title }}</span>
                                <i class="el-icon-rank drag-handle"></i>
                                <el-button icon="el-icon-plus" @click.stop="addComponentAt(index + 1)" size="mini" circle />
                            </div>
                        </div>

                        <div class="drag-actions">
                            <el-button @click="resetOrder" size="small">重置顺序</el-button>
                            <el-button type="primary" @click="applyOrder" size="small">应用排序</el-button>
                        </div>
                    </div>
                </el-tab-pane>
            </el-tabs>
        </div>
    </div>
</template>

<script>
import _ from 'lodash';
import {mapState} from "vuex";

export default {
    data() {
        const initialConfig = {
            banner: { items: [] },
            iconNav: {
                itemsPerRow: 4,
                items: [],
                style: {
                    fontSize: 14,
                    textColor: '#333',
                    itemGap: 12,
                    blockMargin: 20
                }
            },
            products: {
                layout: 'grid',
                items: [],
                style: {
                    fontSize: 14,
                    textColor: '#222',
                    itemGap: 16,
                    blockMargin: 24,
                    layoutType: 'grid'
                }
            }
        };

        return {
            bannerImng:{
                thumb:"",
            },
            clas_id:"",
            orderListMap:"",
            bannerImage:"",
            activeTab: 'settings',
            activeCollapse: ['banner'],
            pageConfig: _.cloneDeep(initialConfig),
            savedConfig: _.cloneDeep(initialConfig),
            selectedComponent: null,
            componentOrder: [
                { name: 'banner', title: '轮播图', icon: 'el-icon-picture' },
                { name: 'iconNav', title: '图标导航', icon: 'el-icon-menu' },
                { name: 'products', title: '商品推荐', icon: 'el-icon-goods' }
            ],
            originalOrder: [
                { name: 'banner', title: '轮播图', icon: 'el-icon-picture' },
                { name: 'iconNav', title: '图标导航', icon: 'el-icon-menu' },
                { name: 'products', title: '商品推荐', icon: 'el-icon-goods' }
            ],
            maskVisible: false,
            addingSecondItemIds: [], // 支持多个 item 同时添加二级分类
            banner_type: 4, // 默认第四种
            bannerTypeOptions: [
                { type: 1, label: '布局1', icon: 'layout1' }, // [1,1]
                { type: 2, label: '布局2', icon: 'layout2' }, // [2,1]
                { type: 3, label: '布局3', icon: 'layout3' }, // [1,2]
                { type: 4, label: '布局4', icon: 'layout4' }, // [1]
            ],
            bannerBgc: '',
            clasBgc: '',
            recommendGoodsBgc: '',
        };
    },
    computed: {
        ...mapState(["userInfo"]),
        isDirty() {
            return !_.isEqual(this.pageConfig, this.savedConfig) || this.banner_type !== (this.savedConfig.banner_type || 4);
        }
    },
    mounted() {
        this.clas_id = this.$route.query.clas_id
        this.fetchOrderAndConfig();
        window.addEventListener('message', this.handleEditorMessage);
        window.addEventListener('beforeunload', this.handleBeforeUnload);

        // 启用编辑模式
        this.enableEditMode();
        // 页面加载时主动同步顺序到前台
        this.syncOrderToIframe();
        // 新增：监听前台顺序变化，保持和后台一致
        window.addEventListener('message', this.handleOrderSyncFromIframe);
    },
    beforeDestroy() {
        window.removeEventListener('message', this.handleEditorMessage);
        window.removeEventListener('beforeunload', this.handleBeforeUnload);
        window.removeEventListener('message', this.handleOrderSyncFromIframe);
    },
    methods: {
        toShopDetail(e) {
            this.$router.push({
                path: '/shop/manage',
                query: {
                    id: e.id
                }
            })
        },
        getIframeSrc() {
            const queryParam = this.clas_id ? `clas_id=${encodeURIComponent(this.clas_id)}` : '';
            // return `http://175.178.253.101:8081/rightType/second/index?${queryParam}`;
            return `http://192.168.31.105:8081/rightType/second/index?${queryParam}`;
        },
        editThird(e){
            this.$router.replace(`/shopDecoration/third?clas_id=${e.id}`)
        },

        fetchOrderAndConfig() {
            console.log(this.clas_id)
            const params = {
                clas_id:this.clas_id,
                type:2
            }
            this.$http.get('/admin/diy/getShopIndex',{params}).then(result => {
                if (result.code === 200) {
                    let layout = {};
                    if (result.data.layout) {
                        try {
                            layout = typeof result.data.layout === 'string' ? JSON.parse(result.data.layout) : result.data.layout;
                        } catch (e) {
                            layout = {};
                        }
                    }
                    // banner_type 映射
                    if (layout.banner_index) {
                        const map = {
                            '1,1': 1,
                            '2,1': 2,
                            '1,2': 3,
                            '1': 4
                        };
                        const key = layout.banner_index.join(',');
                        this.banner_type = map[key] || 1;
                        console.log('接口返回:', layout.banner_index, '映射key:', key, '最终banner_type:', this.banner_type);
                    } else {
                        this.banner_type = 1;
                    }
                    // 分类一行显示几个
                    if (layout.clas) {
                        this.pageConfig.iconNav.itemsPerRow = layout.clas;
                    } else {
                        this.pageConfig.iconNav.itemsPerRow = 4;
                    }
                    if (layout.banner_index_bgc) this.bannerBgc = layout.banner_index_bgc;
                    if (layout.clas_bgc) this.clasBgc = layout.clas_bgc;
                    if (layout.recommend_goods_bgc) this.recommendGoodsBgc = layout.recommend_goods_bgc;
                    this.savedConfig = _.cloneDeep(this.pageConfig);
                    this.savedConfig.banner_type = this.banner_type;
                    const data = result.data;
                    // 修正顺序映射，保证和接口 order 一致
                    const orderArr = data.order;
                    const orderMap = {
                        banner_index: { name: 'banner', title: '轮播图', icon: 'el-icon-picture' },
                        clas: { name: 'iconNav', title: '图标导航', icon: 'el-icon-menu' },
                        recommend_goods: { name: 'products', title: '商品推荐', icon: 'el-icon-goods' }
                    };
                    this.componentOrder = (orderArr || []).map(key => orderMap[key]).filter(Boolean);
                    // 更新orderListMap以保持同步
                    this.orderListMap = orderArr || [];
                    this.pageConfig.banner.items = (data.banner_index || []).map(item => ({
                        id: item.id,
                        name: item.name,
                        thumb: item.thumb,
                        type: item.type || 1,
                        imageUrl: item.thumb ? $appConfig.baseUrl + item.thumb : '',
                        ...(typeof item.state === 'number' && item.state === -1 ? { state: -1 } : {})
                    }));
                    this.pageConfig.iconNav.items = (data.clas || []).map(item => ({
                        id: item.id,
                        name: item.name,
                        icon: item.icon,
                        type: item.type || 1,
                        imageUrl: item.icon ? $appConfig.baseUrl + item.icon : '',
                        textColor: '#333333',
                        fontSize: 12,
                        style: item.style || {},
                        ...(typeof item.state === 'number' && item.state === -1 ? { state: -1 } : {})
                    }));
                    this.pageConfig.products.items = (data.recommend_goods || []).map(item => ({
                        id: item.id,
                        title: item.title,
                        f_thumb: item.f_thumb || item.thumb,
                        type: item.type || 1,
                        imageUrl: (item.f_thumb || item.thumb) ? $appConfig.baseUrl + (item.f_thumb || item.thumb) : '',
                        price: item.price,
                        style: item.style || {},
                        ...(typeof item.state === 'number' && item.state === -1 ? { state: -1 } : {})
                    }));
                    this.pageConfig.iconNav.style = data.iconNav?.style || _.cloneDeep(initialConfig.iconNav.style);
                    this.pageConfig.products.style = data.products?.style || _.cloneDeep(initialConfig.products.style);

                    this.syncOrderToIframe();
                }
            });
        },

        // 启用编辑模式
        enableEditMode() {
            const iframe = this.$refs.previewIframe;
            if (iframe && iframe.contentWindow) {
                iframe.contentWindow.postMessage({
                    type: 'setEditMode',
                    payload: true
                }, '*');
            }
        },

        // 选择组件
        selectComponent(componentName) {
            this.selectedComponent = componentName;
            this.activeCollapse = [componentName];

            // 通知iframe聚焦到对应组件
            const iframe = this.$refs.previewIframe;
            if (iframe && iframe.contentWindow) {
                iframe.contentWindow.postMessage({
                    type: 'focusComponent',
                    payload: componentName
                }, '*');
            }
        },

        // 拖拽开始
        handleDragStart(event, index) {
            event.dataTransfer.setData('text/plain', index);
        },

        // 拖拽放置
        handleDrop(event, index) {
            const fromIndex = parseInt(event.dataTransfer.getData('text/plain'));
            const toIndex = index;
            if (fromIndex !== toIndex) {
                const item = this.orderListMap.splice(fromIndex, 1)[0];
                this.orderListMap.splice(toIndex, 0, item);
            }
        },

        // 重置顺序
        resetOrder() {
            this.componentOrder = _.cloneDeep(this.originalOrder);
        },

        // 应用排序
        applyOrder() {
            // 顺序字段用这三个key，带编号
            const typeCount = {};
            // 直接用orderListMap生成componentOrder
            const orderArr = this.orderListMap.slice();
            const orderMap = {
                banner_index: { name: 'banner', title: '轮播图', icon: 'el-icon-picture' },
                clas: { name: 'iconNav', title: '图标导航', icon: 'el-icon-menu' },
                recommend_goods: { name: 'products', title: '商品推荐', icon: 'el-icon-goods' }
            };
            this.componentOrder = orderArr.map(key => orderMap[key] || { name: key, title: key, icon: '' });
            // 生成orderArr（带编号）
            const orderArrWithNum = this.componentOrder.map(item => {
                let key = '';
                if (item.name.startsWith('banner')) key = 'banner_index';
                else if (item.name.startsWith('iconNav')) key = 'clas';
                else if (item.name.startsWith('products')) key = 'recommend_goods';
                else key = item.name;
                if (!typeCount[key]) typeCount[key] = 1;
                else typeCount[key]++;
                return typeCount[key] === 1 ? key : `${key}_${String(typeCount[key]).padStart(2, '0')}`;
            });
            this.orderListMap = orderArrWithNum;
            const payload = {
                order: orderArrWithNum,
                banner_index: this.pageConfig.banner?.items || [],
                clas: this.pageConfig.iconNav?.items || [],
                recommend_goods: this.pageConfig.products?.items || [],
                iconNav: { style: this.pageConfig.iconNav.style },
                products: { style: this.pageConfig.products.style }
            };
            // 自动补充order里所有带编号的字段
            orderArrWithNum.forEach(key => {
                if (!(key in payload) && (key.startsWith('banner_index') || key.startsWith('clas') || key.startsWith('recommend_goods'))) {
                    payload[key] = [];
                }
            });
            this.$http.post('/admin/diy/edit', {change:JSON.stringify(payload),type:2}).then(() => {
                this.fetchOrderAndConfig();
                this.syncOrderToIframe();
                this.$message.success('排序已应用');
            });
        },

        // 新增：插入新板块
        addComponentAt(index) {
            this.$prompt('请输入要插入的板块类型（banner、iconNav、products）', '添加板块', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
            }).then(({ value }) => {
                let config = null;
                let baseName = '';
                let baseTitle = '';
                let baseIcon = '';

                if (value === 'banner') {
                    baseName = 'banner';
                    baseTitle = '轮播图';
                    baseIcon = 'el-icon-picture';
                } else if (value === 'iconNav') {
                    baseName = 'iconNav';
                    baseTitle = '图标导航';
                    baseIcon = 'el-icon-menu';
                } else if (value === 'products') {
                    baseName = 'products';
                    baseTitle = '商品推荐';
                    baseIcon = 'el-icon-goods';
                }

                if (baseName) {
                    // 检查是否已存在相同类型的板块
                    const existingComponents = this.componentOrder.filter(item => item.name.startsWith(baseName));

                    if (existingComponents.length > 0) {
                        // 如果已存在，添加数字标识
                        const suffix = (existingComponents.length + 1).toString().padStart(2, '0');
                        config = {
                            name: `${baseName}_${suffix}`,
                            title: `${baseTitle}_${suffix}`,
                            icon: baseIcon
                        };
                    } else {
                        // 如果不存在，使用原始名称
                        config = { name: baseName, title: baseTitle, icon: baseIcon };
                    }

                    this.componentOrder.splice(index, 0, config);
                } else {
                    this.$message.error('板块类型不正确');
                }
            });
        },

        handleBannerUploadSuccess(response, file, fileList, bannerId, bannerUuid) {
            let banner;
            if (bannerUuid) {
                banner = this.pageConfig.banner.items.find(item => item._uuid === bannerUuid);
            } else {
                banner = this.pageConfig.banner.items.find(item => item.id === bannerId);
            }
            if (banner) {
                banner.thumb = response.data[0];
                banner.imageUrl = $appConfig.baseUrl + response.data[0];
            }
            this.$message.success('文件上传成功');
        },
        handleIconUploadSuccess(response, file, fileList, iconId, iconUuid) {
            let icon;
            if (iconUuid) {
                icon = this.pageConfig.iconNav.items.find(item => item._uuid === iconUuid);
            } else {
                icon = this.pageConfig.iconNav.items.find(item => item.id === iconId);
            }
            if (icon) {
                icon.icon = response.data[0];
                icon.imageUrl = $appConfig.baseUrl + response.data[0];
            }
            this.$message.success('文件上传成功');
        },
        handleProductUploadSuccess(response, file, fileList, productId, productUuid) {
            let product;
            if (productUuid) {
                product = this.pageConfig.products.items.find(item => item._uuid === productUuid);
            } else {
                product = this.pageConfig.products.items.find(item => item.id === productId);
            }
            if (product) {
                product.f_thumb = response.data[0];
                product.imageUrl = $appConfig.baseUrl + response.data[0];
            }
            this.$message.success('文件上传成功');
        },
        beforeExcelUpload(file) {
            // 允许的图片类型
            const isImage =
                file.type === 'image/jpeg' ||
                file.type === 'image/png' ||
                file.type === 'image/jpg'; // 注：标准 MIME 类型中 jpg 对应 image/jpeg，这里保留兼容写法

            // 限制文件大小为 500KB
            const isLt20M = file.size / 1024 / 1024 < 20;

            if (!isImage) {
                this.$message.error('请上传JPG、PNG、JPEG格式的图片!');
            }
            if (!isLt20M) {
                this.$message.error('图片大小不能超过20M!');
            }

            return isImage && isLt20M;
        },
        onIframeLoad() {
            this.updatePreview();
        },
        updatePreview() {
            const iframe = this.$refs.previewIframe;
            if (iframe && iframe.contentWindow) {
                iframe.contentWindow.postMessage({
                    type: 'updateConfig',
                    payload: this.pageConfig
                }, '*');
            }
        },
        saveChanges() {
            const banners = (this.pageConfig.banner.items || []).filter(item => {
                const old = (this.savedConfig.banner.items || []).find(o => o.id === item.id) || {};
                return item.thumb !== old.thumb || item.name !== old.name || item.state !== old.state || item.type !== old.type;
            }).map(item => {
                const result = { thumb: item.thumb || '', name: item.name || '', type: item.type || 1 };
                if (item.id !== undefined && item.id !== null) result.id = item.id;
                if (item.state === -1) result.state = -1;
                return result;
            });

            const icons = (this.pageConfig.iconNav.items || []).filter(item => {
                const old = (this.savedConfig.iconNav.items || []).find(o => o.id === item.id) || {};
                return item.icon !== old.icon || item.name !== old.name || item.state !== old.state || item.type !== old.type;
            }).map(item => {
                const result = {
                    icon: item.icon || '',
                    name: item.name || '',
                    type: item.type || 1,
                    style: {
                        fontSize: item.style?.fontSize,
                        textColor: item.style?.textColor,
                        itemGap: item.style?.itemGap,
                        blockMargin: item.style?.blockMargin
                    }
                };
                if (item.id !== undefined && item.id !== null) result.id = item.id;
                if (item.state === -1) result.state = -1;
                return result;
            });

            const products = (this.pageConfig.products.items || []).filter(item => {
                const old = (this.savedConfig.products.items || []).find(o => o.id === item.id) || {};
                return item.f_thumb !== old.f_thumb || item.title !== old.title || item.state !== old.state || item.type !== old.type;
            }).map(item => {
                const result = {
                    f_thumb: item.f_thumb || '',
                    title: item.title || '',
                    type: item.type || 1,
                    style: {
                        fontSize: item.style?.fontSize,
                        textColor: item.style?.textColor,
                        itemGap: item.style?.itemGap,
                        blockMargin: item.style?.blockMargin,
                        layoutType: item.style?.layoutType
                    }
                };
                if (item.id !== undefined && item.id !== null) result.id = item.id;
                if (item.is_recommend === 1) result.is_recommend = 1;
                if (item.state === -1) result.state = -1;
                return result;
            });

            // 根据当前componentOrder生成order数组，带编号
            const typeCount = {};
            const orderArr = this.componentOrder.map(item => {
                let key = '';
                if (item.name.startsWith('banner')) key = 'banner_index';
                else if (item.name.startsWith('iconNav')) key = 'clas';
                else if (item.name.startsWith('products')) key = 'recommend_goods';
                else key = item.name;
                if (!typeCount[key]) typeCount[key] = 1;
                else typeCount[key]++;
                return typeCount[key] === 1 ? key : `${key}_${String(typeCount[key]).padStart(2, '0')}`;
            });

            // 样式字段列表
            const iconNavStyleKeys = ['fontSize', 'textColor', 'itemGap', 'blockMargin'];
            const productsStyleKeys = ['fontSize', 'textColor', 'itemGap', 'blockMargin', 'layoutType'];

            // clas
            const clas = this.pageConfig.iconNav.items.map(item => {
                const style = {};
                iconNavStyleKeys.forEach(key => {
                    if (this.pageConfig.iconNav.style[key] !== undefined) style[key] = this.pageConfig.iconNav.style[key];
                    if (item.style && item.style[key] !== undefined) style[key] = item.style[key];
                });
                const data = { ...item };
                iconNavStyleKeys.forEach(key => { delete data[key]; });
                if (this.addingSecondItemIds && this.addingSecondItemIds.includes(item.id)) {
                    // 只保留pid，不保留原id
                    const { id, ...rest } = data;
                    return { ...rest, pid: id, style: item.style ? { ...style, ...item.style } : style };
                }
                return { ...data, style: item.style ? { ...style, ...item.style } : style };
            }).filter(Boolean);

            // recommend_goods
            const recommend_goods = this.pageConfig.products.items.map(item => {
                const style = {};
                productsStyleKeys.forEach(key => {
                    if (this.pageConfig.products.style[key] !== undefined) style[key] = this.pageConfig.products.style[key];
                    if (item.style && item.style[key] !== undefined) style[key] = item.style[key];
                });
                const data = { ...item };
                productsStyleKeys.forEach(key => { delete data[key]; });
                return { ...data, style };
            });

            // 新增：layout字段
            // banner_index: [1,1]（左一右一）、[1,2]（左一右二）、[2,1]（左二右一）、[1]（一整个banner）
            let banner_index_layout = [1,1];
            if (this.banner_type === 4) banner_index_layout = [1];
            else if (this.banner_type === 1) banner_index_layout = [1,1];
            else if (this.banner_type === 2) banner_index_layout = [2,1];
            else if (this.banner_type === 3) banner_index_layout = [1,2];
            // 分类一行显示个数
            const clas_layout = this.pageConfig.iconNav.itemsPerRow || 4;
            // 商品推荐写死2
            const recommend_goods_layout = 2;
            const layout = {
                banner_index: banner_index_layout,
                clas: clas_layout,
                recommend_goods: recommend_goods_layout
            };
            layout.banner_index_bgc = this.bannerBgc;
            layout.clas_bgc = this.clasBgc;
            layout.recommend_goods_bgc = this.recommendGoodsBgc;

            const newObj = {
                order: orderArr,
                layout,
                clas_id: this.clas_id,
                banner_type: this.banner_type
            };

            // 确保三个字段始终存在，即使没有数据也传递空数组
            newObj.banner_index = banners;
            newObj.clas = clas;
            newObj.recommend_goods = recommend_goods;

            // 自动补充order里所有带编号的字段
            orderArr.forEach(key => {
                if (!(key in newObj) && (key.startsWith('banner_index') || key.startsWith('clas') || key.startsWith('recommend_goods'))) {
                    newObj[key] = [];
                }
            });
            this.$http.post('/admin/diy/edit', {
                change: JSON.stringify(newObj),
                type:2,
                clas_id: this.clas_id
            }).then(res => {
                if (res.code === 200) {
                    this.$message.success('保存成功');
                    this.fetchOrderAndConfig(); // 强制刷新数据，保证和后端同步
                    this.savedConfig = _.cloneDeep(this.pageConfig); // 确保取消时有快照
                    this.addingSecondItemIds = [];
                } else {
                    this.$message.error(res.message || '保存失败');
                }
            });
        },

        cancelChanges() {
            // 整体还原，保证结构和数据完整
            this.pageConfig = _.cloneDeep(this.savedConfig);
            this.$forceUpdate();
            this.updatePreview();
            this.$message.info('更改已取消');
        },
        handleBeforeUnload(e) {
            if (this.isDirty) {
                e.preventDefault();
                e.returnValue = ''; // Required for Chrome
                return ''; // For other browsers
            }
        },
        handleEditorMessage(event) {
            const { type, component, payload } = event.data;
            if (type === 'componentSelected') {
                // 映射组件名称
                let mappedComponent = component;
                if (component === 'banner') mappedComponent = 'banner';
                else if (component === 'quickEntry') mappedComponent = 'iconNav';
                else if (component === 'productRecommend') mappedComponent = 'products';

                this.selectedComponent = mappedComponent;
                this.activeCollapse = [mappedComponent];
                this.activeTab = 'settings';
                this.$nextTick(() => {
                    const refMap = {
                        banner: 'bannerCollapse',
                        iconNav: 'iconNavCollapse',
                        products: 'productsCollapse'
                    };
                    const refName = refMap[mappedComponent];
                    if (refName && this.$refs[refName] && this.$refs[refName][0]) {
                        this.$refs[refName][0].$el.scrollIntoView({ behavior: 'smooth', block: 'start' });
                    }
                });
            } else if (type === 'focusComponent') {
                // 处理跳转到对应设置板块
                let mappedComponent = payload;
                if (payload === 'banner') mappedComponent = 'banner';
                else if (payload === 'iconNav') mappedComponent = 'iconNav';
                else if (payload === 'products') mappedComponent = 'products';

                this.selectedComponent = mappedComponent;
                this.activeCollapse = [mappedComponent];
                this.activeTab = 'settings';
                this.$nextTick(() => {
                    const refMap = {
                        banner: 'bannerCollapse',
                        iconNav: 'iconNavCollapse',
                        products: 'productsCollapse'
                    };
                    const refName = refMap[mappedComponent];
                    if (refName && this.$refs[refName] && this.$refs[refName][0]) {
                        this.$refs[refName][0].$el.scrollIntoView({ behavior: 'smooth', block: 'start' });
                    }
                });
            }
        },
        updateConfig(newConfig) {
            this.pageConfig = newConfig;
        },
        // 新增：主动同步顺序到前台
        syncOrderToIframe() {
            const iframe = this.$refs.previewIframe;
            if (iframe && iframe.contentWindow) {
                iframe.contentWindow.postMessage({
                    type: 'updateComponentOrder',
                    payload: this.componentOrder.map(item => item.name)
                }, '*');
            }
        },
        // 新增：监听前台顺序变化，保持和后台一致
        handleOrderSyncFromIframe(event) {
            const { type, payload } = event.data;
            if (type === 'updateComponentOrder' && Array.isArray(payload)) {
                // 只要顺序不同步就更新
                const backendOrder = this.componentOrder.map(item => item.name);
                if (JSON.stringify(backendOrder) !== JSON.stringify(payload)) {
                    // 重新排序后台componentOrder
                    const newOrder = [];
                    payload.forEach(name => {
                        const found = this.componentOrder.find(item => item.name === name);
                        if (found) newOrder.push(found);
                    });
                    // 补充后台有但前台没有的
                    this.componentOrder.forEach(item => {
                        if (!payload.includes(item.name)) newOrder.push(item);
                    });
                    this.componentOrder = newOrder;
                }
            } else if (type === 'updateComponentOrder') {
                // 重新拉取接口配置，保证顺序和内容都和后台一致
                this.fetchPageConfig();
            }
        },

        addBannerAfter(banner) {
            const arr = this.pageConfig.banner.items;
            const idx = arr.indexOf(banner);
            const newBanner = { name: '', thumb: '', imageUrl: '', type: 1, _uuid: Date.now() + Math.random() };
            arr.splice(idx + 1, 0, newBanner);
        },
        addFirstBanner() {
            const newBanner = { name: '', thumb: '', imageUrl: '', type: 1, _uuid: Date.now() + Math.random() };
            this.pageConfig.banner.items.push(newBanner);
        },
        addIconNavAfter(item) {
            const arr = this.pageConfig.iconNav.items;
            const idx = arr.indexOf(item);
            const newIcon = { name: '', icon: '', imageUrl: '', style: {}, type: 1, _uuid: Date.now() + Math.random() };
            arr.splice(idx + 1, 0, newIcon);
        },
        addFirstIconNav() {
            const newIconNav = { name: '', icon: '', imageUrl: '', style: {}, type: 1, _uuid: Date.now() + Math.random() };
            this.pageConfig.iconNav.items.push(newIconNav);
        },
        addProductAfter(product) {
            const arr = this.pageConfig.products.items;
            const idx = arr.indexOf(product);
            const newProduct = { title: '', f_thumb: '', imageUrl: '', price: '', style: {}, type: 1, is_recommend: 1, _uuid: Date.now() + Math.random() };
            arr.splice(idx + 1, 0, newProduct);
        },
        addFirstProduct() {
            const newProduct = { title: '', f_thumb: '', imageUrl: '', price: '', style: {}, type: 1, is_recommend: 1, _uuid: Date.now() + Math.random() };
            this.pageConfig.products.items.push(newProduct);
        },
        removeBanner(banner) {
            this.$confirm('是否确认删除此版块？', '提示', {
                confirmButtonText: '确认',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$set(banner, 'state', -1);
                this.$message.success('删除成功，请点击保存真实删除');
            });
        },
        removeIconNav(item) {
            this.$confirm('是否确认删除此版块？', '提示', {
                confirmButtonText: '确认',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$set(item, 'state', -1);
                this.$message.success('删除成功，请点击保存真实删除');
            });
        },
        removeProduct(product) {
            this.$confirm('是否确认删除此版块？', '提示', {
                confirmButtonText: '确认',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$set(product, 'state', -1);
                this.$message.success('删除成功，请点击保存真实删除');
            });
        },
        // 在 methods 里添加一个方法用于切换banner_type并触发脏状态
        selectBannerType(type) {
            if (this.banner_type !== type) {
                this.banner_type = type;
                this.$forceUpdate();
            }
        },
    },
    /* watch: {
         'pageConfig.iconNav.style': {
             handler(newVal) {
                 console.log('iconNav style changed:', newVal);
             },
             deep: true
         },
         'pageConfig.products.style': {
             handler(newVal) {
                 console.log('products style changed:', newVal);
             },
             deep: true
         },
         'pageConfig.iconNav.items': {
             handler(newVal) {
                 console.log('iconNav items changed:', newVal);
             },
             deep: true
         },
         'pageConfig.products.items': {
             handler(newVal) {
                 console.log('products items changed:', newVal);
             },
             deep: true
         }
     },*/
    beforeRouteLeave(to, from, next) {
        if (this.isDirty) {
            this.$confirm('您有未保存的更改，确定要离开吗?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                next();
            }).catch(() => {
                next(false);
            });
        } else {
            next();
        }
    }
};
</script>

<style scoped lang="less">
.page-container {
    display: flex;
    height: calc(100vh - 50px); // Assuming a 50px header, adjust if needed
    background-color: #f7f8fa;
}

.preview-section {
    flex: 1;
    display: flex;
    justify-content: center;
    //align-items: center;
    padding: 10px;
}

.mobile-mockup {
    width: 375px;
    height: 850px;
    background-color: #fff;
    border-radius: 30px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
    padding: 15px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;

    .iframe-container {
        flex: 1;
        background: white;
        border-radius: 15px;
        overflow: hidden;
        position: relative;
    }

    .iframe-overlay {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 10;
        pointer-events: none;

        .hotspot {
            position: absolute;
            left: 0;
            right: 0;
            pointer-events: auto;
            // background-color: rgba(255, 0, 0, 0.2); // Uncomment for debugging
            cursor: pointer;
        }
    }

    .preview-iframe {
        width: 100%;
        height: 100%;
        border: none;
    }
}

.editor-section {
    width: 450px;
    background-color: #fff;
    border-left: 1px solid #ebedf0;
    padding: 20px;
    box-sizing: border-box;
    overflow-y: auto;
}

.setting-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;

    span {
        font-size: 14px;
    }
}

/deep/ .el-collapse-item__header {
    font-size: 16px;
    font-weight: bold;
}

.editor-content {
    flex: 1;
    overflow-y: auto;
    padding: 0 20px;
}

.editor-footer {
    padding: 15px 20px;
    border-top: 1px solid #ebedf0;
    text-align: right;
}

.setting-block {
    margin-bottom: 20px;
    padding-bottom: 20px;
    border-bottom: 1px solid #f2f2f2;
    &:last-child {
        border-bottom: none;
    }

    p {
        font-weight: 500;
        margin-bottom: 10px;
    }
}

.editor-image {
    width: 250px;
    height: 120px;
    display: block;
}
.editor-icon {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    margin-right: 10px;
}

.inline-settings {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 10px;
}

// 拖拽相关样式
.drag-section {
    padding: 20px;
}

.drag-tip {
    color: #666;
    font-size: 14px;
    margin-bottom: 20px;
}

.component-list {
    margin-bottom: 20px;
}

.component-item {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    margin-bottom: 8px;
    background: #f8f9fa;
    border: 2px solid transparent;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.3s ease;

    &:hover {
        background: #e9ecef;
        border-color: #007bff;
    }

    &.selected {
        background: #e3f2fd;
        border-color: #2196f3;
    }

    i {
        margin-right: 12px;
        font-size: 18px;
        color: #666;
    }

    span {
        flex: 1;
        font-size: 14px;
        color: #333;
    }

    .drag-handle {
        cursor: grab;
        color: #999;

        &:active {
            cursor: grabbing;
        }
    }
}

.drag-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
}

.iframe-container { position: relative; }

.banner-type-selector {
    display: flex;
    gap: 10px;
    margin-bottom: 16px;
    justify-content: flex-start;
    .banner-type-item {
        cursor: pointer;
        border: 2px solid #1ec6b6;
        border-radius: 6px;
        padding: 4px 6px 2px 6px;
        background: #e6f7ff;
        transition: box-shadow 0.2s, border-color 0.2s, background 0.2s;
        display: flex;
        flex-direction: column;
        align-items: center;
        min-width: 54px;
        &.active {
            box-shadow: 0 0 0 2px #1ec6b6;
            background: #b2f1e9;
            border-color: #2db7f5;
        }
        .banner-type-icon-v2 {
            position: relative;
            width: 34px;
            height: 24px;
            margin-bottom: 2px;
            background: #fff;
            border-radius: 4px;
            border: 1.2px solid #1ec6b6;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .rect {
            position: absolute;
            border: 1.5px solid #1ec6b6;
            border-radius: 2px;
            background: transparent;
        }
        .rect.big {
            /* 大块 */
        }
        .rect.small {
            /* 小块 */
        }
    }
}
</style>





